-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support !Sync (and maybe !Send) Context #840
Support !Sync (and maybe !Send) Context #840
Conversation
Notably updated actix, tokio, and juniper. Juniper now requires Send + Sync for context, prompting me to open graphql-rust/juniper#840 The file streaming code has been replaced by the ones provided by actix, as they support everything we need now. Signed-off-by: Mcat12 <[email protected]>
@Mcat12 so this PR makes |
Not quite, or at least that's not the goal. I noted some of the current roadblocks in detail in the description, but basically juniper should be able to support Juniper's core machinery is synchronous, operating within one future chain. The asynchrony comes from the user's resolver code, which can be async functions. This synchronous behavior supports having The PR description notes some reasons why that is not the case currently, most notably that async functions cannot appear in traits due to a lack of GATs (Generic Associated Types). See for example If you would like, I can mark this PR as a draft since it is unlikely to be merge-able in the short term. Edit: Regarding |
@Mcat12 the biggest blocker is GAT, of course. The fact that Things like whether runtime supports
Yeah, that would be nice.
And it shouldn't, as for me. Running |
Although it's somewhat unrelated to the core juniper library, this is where |
Closing this PR since any future progress will require starting from scratch. |
When upgrading juniper from 0.9 to 0.15, I found that context types now require
Send + Sync
. Previously, before juniper was async, everything was synchronous and the context could contain!Sync
types such as database connections (ex. SQLite). This PR experiments with removing theSync
requirement (andSend
, since the context is only ever referenced not owned).There are some roadblocks which I'm not sure can be resolved at this time. The juniper futures now are
!Send
since they hold a reference to the!Sync
context. This is fine in the core juniper library and juniper_actix, but web services based on tokio/hyper have issues with spawning!Send
futures. Tokio supports spawning!Send
futures, but only when using aLocalSet
, which is only really feasible when using the single-threaded runtime. There is a (recently closed, but in-discussion) issue which addresses spawning!Send
futures on the multi-threaded runtime: tokio-rs/tokio#2545. Due to this issue, Hyper only supports!Send
futures when using the single-threaded runtime: https://github.com/hyperium/hyper/blob/8861f9a7867216c81ea14ac6224c11a1303e7761/examples/single_threaded.rs. Warp does not support!Send
yet: seanmonstar/warp#528. It's not clear how Rocket 0.5 will handle!Send
, but since it's based on hyper it won't be any better than what they provide.Theoretically the future that runs the graphql resolver could be
Send
because the!Sync
context is owned by the future and passed into juniper by reference. However, because GATs (Generic Abstract Types) are not implemented, traits with async methods must box their futures. This causes juniper's future to holdLocalBoxFuture
s, which are notSend
. Due to this, the overall future is notSend
... If GATs were implemented, it may be possible to avoid the tokio!Send
futures issue by convincing Rust that the overall juniper resolve future isSend
since the context is owned by the calling code (the web handler which calls juniper) which is part of the same future object.The main changes include:
Send
andSync
bounds on context types.BoxFuture
withLocalBoxFuture
(similar for streams), due to the removal ofContext: Sync
.juniper_hyper
examples and tests to use a single-threaded runtime due to the above issues.juniper_warp
in an attempt to support!Send
futures, but this fails at runtime due to the lack of support in warp for!Send
futures (see issue link above).ExecutionParams
so that the context is not captured in the error type, which would require the context to beSend
. This is safe because the error object only refers to data in the request and schema, not the context (see the lifetimes onjuniper::execute
).I don't really expect this PR to be merged any time soon, if at all, but it's worth bringing up the issue and showing how the core juniper library can support
!Sync
(and even!Send
) context. The issues lie in the web server integration libraries, mainly due to the lack of GATs and issues in tokio with spawning!Send
futures.Related juniper issues: